package xyz.lwm.lazycat.beans;

import org.jetbrains.annotations.NotNull;
import xyz.lwm.lazycat.annotation.Inject;

import java.lang.annotation.Annotation;
import java.util.Map;

/**
 * <h3>Bean 容器</h3>
 * <p>容器获取方式:</p>
 *
 * <p>1. 使用 {@link BeansCustomizer} 获取</p>
 * <pre>{@code
 * @Bean
 * public class MyBeansCustomizer implements BeansCustomizer {
 *     private Beans beans;
 *     @Override
 *     public void customize(BeanDesignRegistry registry, Beans beans) {
 *         this.beans = beans;
 *     }
 * }
 * }</pre>
 *
 * <p>2. 使用 {@link Inject} 获取</p>
 * <pre>{@code
 * @Bean
 * public class MyService {
 *     @Inject
 *     private Beans beans;
 * }
 * }</pre>
 *
 * <p>3. 使用 {@link Application} 实例获取 </p>
 * <pre>{@code
 * Application app = new Application();
 * app.start();
 * app.getBeans();;
 * }</pre>
 *
 * @author lwm
 */
public interface Beans {

    /**
     * 根据服务名获取服务实例
     *
     * @param beanName 实例名
     * @return 服务实例
     * @throws BeansException 获取服务失败
     */
    @NotNull <T> T get(@NotNull String beanName) throws BeansException;

    /**
     * 根据服务类型获取服务实例
     *
     * @param clz 服务类型
     * @return 服务实例
     * @throws BeansException 获取服务失败
     */
    @NotNull <T> T get(@NotNull Class<T> clz) throws BeansException;

    /**
     * 根据服务类型获取服务实例 MAP
     *
     * @param clz 服务类型
     * @return 服务实例 LinkedHashMap, MAP 可能为空 map, 但不会 null
     */
    @NotNull <T> Map<String, T> map(@NotNull Class<T> clz);

    /**
     * 根据服务类型以及注解(递归注解)获取服务实例 MAP
     *
     * @param clz 服务类型
     * @param aClz 注解类型
     * @return 服务实例 LinkedHashMap, MAP 可能为空 map, 但不会 null
     */
    @NotNull <T, A extends Annotation> Map<String, T> map(@NotNull Class<T> clz, @NotNull Class<A> aClz);

    /**
     * 根据服务类型以及注解(递归注解)获取服务实例 MAP
     *x
     * @param aClz 注解类型
     * @return 实服务实例 LinkedHashMap, MAP 可能为空 map, 但不会 null
     */
    @NotNull <T, A extends Annotation> Map<String, T> annotatedMap(@NotNull Class<A> aClz);

}
